﻿using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SuperCalculator
{
    public partial class frmFunctionCoding : Form
    {
        private bool isTextChanged = false;//跟踪文本是否已经被修改
        private bool isNewFunction = false;//指示目前是添加的新函数,还是修改已有函数
        private FunctionInfo funInfo = null;//本函数对应的FunctionInfo对象


        //自动生成部分代码
        private void AutoGenerateCode()
        {
            this.textBoxCoding.Clear();

            string code =
                Environment.NewLine +
                "//不要修改此行代码" + Environment.NewLine +
                "public static double " + this.funInfo.Name + Environment.NewLine +
                "(" + Environment.NewLine +
                "//TODO:在这里修改参数列表" + Environment.NewLine +
                ")" + Environment.NewLine +
                "{" + Environment.NewLine + Environment.NewLine +
                "   //TODO:在这里修改函数体" + Environment.NewLine + Environment.NewLine +
                "   return 0.0;" + Environment.NewLine +
                "}" + Environment.NewLine;

            this.textBoxCoding.Text = code;

        }

        /// <summary>
        /// 保存相关文件
        /// </summary>
        /// <returns></returns>
        private bool Save()
        {
            this.isTextChanged = false;

            string path = Function.DirectoryOfFunctions + this.funInfo.RelativePathOfCodeFile;

            StreamWriter sw = new StreamWriter(path, false, Encoding.Default, 100);
            try
            {
                sw.Write(this.textBoxCoding.Text);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error at save codefile:\n" + ex);
                return false;
            }
            finally
            {
                sw.Close();
            }

            return true;
        }

        /// <summary>
        /// 删除相关文件
        /// </summary>
        /// <returns></returns>
        private bool Delete()
        {
            //编译未通过时,删除可能带来错误的代码文件
            //带来错误的可能是函数代码,也可能是用户修改了using
            string path1 = Function.DirectoryOfFunctions + this.funInfo.RelativePathOfCodeFile;
            string path2 = Function.GetPathOfUsingFile();

            try
            {
                Function.CollectionOfFunctionInfo.Remove(this.funInfo);
                Function.SaveFunctionsToList();
            }
            catch { }

            try
            {
                File.Delete(path1);
                File.Delete(path2);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error at save delete FunctionCodeFile:\n" + ex);
                return false;
            }

            return true;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="fInfo">该函数对应的FunctionInfo对象</param>
        /// <param name="isNewFunction">指示目前是添加的新函数,还是修改已有函数</param>
        public frmFunctionCoding(FunctionInfo fInfo, bool isNewFunction)
        {
            this.funInfo = fInfo;
            this.isNewFunction = isNewFunction;
            InitializeComponent();

        }

        private void textBoxCoding_TextChanged(object sender, EventArgs e)
        {
            this.isTextChanged = true;
        }

        private void frmFunctionCoding_Load(object sender, EventArgs e)
        {
            this.Closing += new CancelEventHandler(FormFunctionCoding_Closing);
            this.labelFunctionName.Text = this.funInfo.Name + "函数编辑";

            //如果是新函数则自动创建部分代码
            //否则读取该函数的代码
            if (this.isNewFunction)
            {
                this.AutoGenerateCode();
            }
            else
            {
                StreamReader sr = null;
                string code = "";
                try
                {
                    sr = new StreamReader(Function.DirectoryOfFunctions + this.funInfo.RelativePathOfCodeFile, Encoding.Default);
                    code = sr.ReadToEnd();
                    this.textBoxCoding.Text = code;
                    this.isTextChanged = false;
                }
                catch (Exception ex)
                {
                    MessageBox.Show("在读取代码文件时发生错误\n" + ex);
                }
                finally
                {
                    if (sr != null)
                    {
                        sr.Close();
                    }
                }
            }
        }

        void FormFunctionCoding_Closing(object sender, CancelEventArgs e)
        {
            if (this.isTextChanged)
            {
                DialogResult dr = MessageBox.Show("\n\n内容已改变, 保存吗?                           \n\n", "保存",
                    MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);

                if (dr == DialogResult.Yes)
                {
                    this.Save();
                }
                else if (dr == DialogResult.Cancel)
                {
                    e.Cancel = true;
                }

            }
        }

        private void buttonSave_Click(object sender, EventArgs e)
        {
            this.Save();
        }

        //生成函数
        private void buttonMake_Click(object sender, EventArgs e)
        {
            if (!this.Save())
            {
                MessageBox.Show("保存文件失败");
                return;
            }

            CompilerResults res;

            if (CompilerUnit.BuildFunctionDll(out res))
            {

                //如果是新函数,则在主窗口添加相应按钮等等
                if (this.isNewFunction)
                {
                    var fMain = (frmMain)this.Owner;
                    Function.CollectionOfFunctionInfo.Add(this.funInfo);
                    fMain.AddFunctionButtonToForm(this.funInfo);
                    Function.SaveFunctionsToList();
                }
                this.Close();
                string warning = "\n生成成功!  重新启动程序后修改生效. 现在就重新启动程序吗?\n";
                if (MessageBox.Show(warning, "重启程序", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1)
                    == DialogResult.Yes)
                {
                    //重新启动程序--------------------
                    string path = Application.StartupPath + Path.DirectorySeparatorChar +
                                  "ProgramCalculator.exe";//请修改,不可靠的
                    this.Owner.Dispose();
                    System.Diagnostics.Process.Start(path);
                    //---------------------------------
                }
            }
            else
            {
                MessageBox.Show("生成失败\n " + res.Errors[0].ErrorText);

                this.Delete();

                Function.GetPathOfUsingFile();//重要的,这将还原using文件
            }
        }

        //添加using语句
        private void buttonAddUsing_Click(object sender, EventArgs e)
        {
            //重要:备份using文件,用于编译错误时还原using文件
            StreamReader sr = new StreamReader(Function.GetPathOfUsingFile());
            try
            {
                Function.UsingFileBackup = sr.ReadToEnd();
            }
            catch { }
            finally
            {
                sr.Close();
            }
            //------


            frmAddUsing fu = new frmAddUsing();
            fu.ShowDialog(this);
        }

    }
}
